home *** CD-ROM | disk | FTP | other *** search
- Subject: v17i071: Zoo archive program, Part08/10
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Rahul Dhesi <bsu-cs!dhesi@iuvax.cs.indiana.edu>
- Posting-number: Volume 17, Issue 71
- Archive-name: zoo2/part08
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 8 (of 10)."
- # Wrapped by rsalz@papaya.bbn.com on Thu Feb 2 18:04:04 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'portable.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'portable.c'\"
- else
- echo shar: Extracting \"'portable.c'\" \(21282 characters\)
- sed "s/^X//" >'portable.c' <<'END_OF_FILE'
- X#ifndef LINT
- X/* @(#) portable.c 2.24 88/08/24 01:22:06 */
- Xstatic char sccsid[]="@(#) portable.c 2.24 88/08/24 01:22:06";
- X#endif /* LINT */
- X
- X#include "options.h"
- X/*
- XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- X(C) Copyright 1988 Rahul Dhesi -- All rights reserved
- X*/
- X/**********************
- Xportable.c contains functions needed to make Zoo portable to various
- Ximplementations of C.
- X
- XNote: Provided a 2's complement machine is used, all functions in
- Xthis file are themselves machine-independent and need not be changed
- Xwhen implementing Zoo on a different machine. Some code will choke
- Xon 1's complement machines--I think.
- X
- XFor machine-dependent declarations see files "machine.h" and "options.h".
- X
- XFor machine-dependent functions see file "machine.c"
- X*/
- X
- X#include "zooio.h"
- X
- X#include "various.h"
- X#include "zoofns.h"
- X
- X#include "machine.h"
- X#include "zoo.h"
- X#include "debug.h"
- X#include "assert.h"
- X
- X#ifdef NEEDCTYP
- X#include <ctype.h> /* for tolower() */
- X#endif
- X
- X#include "portable.h"
- X
- X#ifdef TRACE_IO
- Xextern int verbose;
- X#endif
- X
- X/* Functions defined for use within this file only. */
- X#ifdef LINT_ARGS
- Xlong to_long (BYTE[]);
- Xint to_int (BYTE[]);
- Xvoid b_to_zooh(struct zoo_header *, BYTE[]);
- Xvoid b_to_dir(struct direntry *, BYTE[]);
- Xint dir_to_b(BYTE[], struct direntry *);
- Xvoid zooh_to_b(BYTE[], struct zoo_header *);
- Xvoid splitlong(BYTE[], long);
- Xvoid splitint(BYTE[], int);
- X#else
- Xlong to_long ();
- Xint to_int ();
- Xvoid b_to_zooh();
- Xvoid b_to_dir();
- Xint dir_to_b();
- Xvoid zooh_to_b();
- Xvoid splitlong();
- Xvoid splitint();
- X#endif
- X
- X#ifdef TRACE_IO
- Xvoid show_h PARMS ((struct zoo_header *));
- Xvoid show_dir PARMS ((struct direntry *));
- X#endif /* TRACE_IO */
- X
- Xextern unsigned int crccode;
- X
- X/************************************************************************/
- X/* I/O functions */
- X/************************************************************************/
- X
- X/* some functions get defined only if they aren't already macros */
- X
- X#ifndef zooread
- Xint zooread (file, buffer, count)
- XZOOFILE file; char *buffer; int count;
- X{ return (fread (buffer, 1, count, file)); }
- X#endif /* zooread */
- X
- X#ifndef FIZ
- X#ifndef zoowrite
- Xint zoowrite (file, buffer, count)
- XZOOFILE file; char *buffer; int count;
- X{
- X if (file == NULLFILE)
- X return (count);
- X else
- X return (fwrite (buffer, 1, count, file));
- X}
- X#endif /* zoowrite */
- X
- XZOOFILE zoocreate (fname)
- Xchar *fname;
- X{ return ((ZOOFILE) fopen (fname, Z_NEW)); }
- X
- X/* truncates a file -- can be empty */
- X/* force use of argument to keep Turbo C happy */
- Xint zootrunc (file) ZOOFILE file; {return ((int) file); }
- X#endif /* FIZ */
- X
- X#ifndef zooseek
- Xlong zooseek (file, offset, whence)
- XZOOFILE file; long offset; int whence;
- X{ return (fseek (file, offset, whence)); }
- X#endif /* zooseek */
- X
- XZOOFILE zooopen (fname, option)
- Xchar *fname; char *option;
- X{ return ((ZOOFILE) fopen (fname, option)); }
- X
- X#ifndef zootell
- Xlong zootell (file)
- XZOOFILE file;
- X{ return ftell (file); }
- X#endif /* zootell */
- X
- Xint zooclose (file)
- XZOOFILE file;
- X{ return fclose (file); }
- X
- X/************************************************************************/
- X/*** Following are functions that make up for various implementations ***/
- X/*** of C not having certain library routines. ***/
- X/************************************************************************/
- X
- X#ifndef FIZ
- X#ifndef STRLWR
- X/**********************
- Xstrlwr() converts a string to lowercase and returns a pointer to the string
- X*/
- Xchar *strlwr (str)
- Xchar *str;
- X{
- X register char *s;
- X s = str;
- X while (*s != '\0') {
- X *s = toascii(*s);
- X if (isupper(*s))
- X *s = tolower(*s);
- X s++;
- X }
- X return (str);
- X}
- X#endif /* STRLWR */
- X
- X/**********************
- Xstrcmpi() compares strings just like strcmp() but it does it without regard to
- Xcase.
- X*/
- Xint strcmpi (s1, s2)
- Xregister char *s1, *s2;
- X{
- X for ( ; tolower(*s1) == tolower(*s2); s1++, s2++)
- X if (*s1 == '\0')
- X return(0);
- X return(tolower(*s1) - tolower(*s2));
- X}
- X
- X#ifndef MEMSET
- X/**********************
- Xmemset() exists in Microsoft C and UNIX System V but not in Xenix. It sets
- Xthe first "cnt" bytes of "dest" to the character "c" and returns a pointer to
- X"dest".
- X*/
- Xchar * memset (dest, c, cnt)
- Xchar *dest;
- Xint c;
- Xunsigned cnt;
- X{
- X register unsigned i;
- X for (i = 0; i < cnt; i++) {
- X *(dest + i) = c;
- X }
- X return (dest);
- X}
- X#endif /* MEMSET */
- X
- X#ifndef FPUTCHAR
- X/**********************
- Xfputchar() writes a character to stdout. It is identical to putchar
- Xbut is a function, not a macro.
- X*/
- Xint fputchar (c)
- Xint c;
- X{
- X return (fputc(c, stdout));
- X}
- X#endif /* FPUTCHAR */
- X#endif /* FIZ */
- X
- X/***********************************************************************/
- X/*** Following are declarations and functions that are written in a ***/
- X/*** machine-independent way but they implement machine-dependent ***/
- X/*** activities ***/
- X/***********************************************************************/
- X
- X#ifndef TURBOC
- X/**********************
- Xto_long() converts four consecutive bytes, in order of increasing
- Xsignificance, to a long integer. It is used to make Zoo independent of the
- Xbyte order of the system.
- X*/
- Xlong to_long(data)
- XBYTE data[];
- X{
- X return (long) ((unsigned long) data[0] | ((unsigned long) data[1] << 8) |
- X ((unsigned long) data[2] << 16) | ((unsigned long) data[3] << 24));
- X}
- X
- X#ifndef FIZ
- X/********************
- Xsplitlong() converts a long integer to four consecutive BYTEs in order
- Xof increasing significance.
- X*/
- Xvoid splitlong(bytes, bigword)
- XBYTE bytes[];
- Xlong bigword;
- X{
- X int i;
- X for (i = 0; i < 4; i++) {
- X bytes[i] = bigword & 0xff;
- X bigword = (unsigned long) bigword >> 8;
- X }
- X}
- X#endif /* FIZ */
- X
- X/*******************
- Xsplitint() converts an integer to two consecutive BYTEs in order
- Xof increasing significance.
- X*/
- Xvoid splitint(bytes, word)
- XBYTE bytes[];
- Xint word;
- X{
- X bytes[0] = word & 0xff;
- X word = (unsigned int) word >> 8;
- X bytes[1] = word & 0xff;
- X}
- X
- X/**********************
- Xto_int() converts two consecutive bytes, in order of increasing
- Xsignificance, to an integer, in a machine-independent manner
- X*/
- Xint to_int(data)
- XBYTE data[];
- X{
- X return (int) ((unsigned int) data[0] | ((unsigned int) data[1] << 8));
- X}
- X
- X#else /* else of ifndef TURBOC */
- X
- Xlong to_long(data)
- XBYTE data[];
- X{
- X return ( * (long *) data );
- X}
- X
- X#ifndef FIZ
- X/********************
- Xsplitlong() converts a long integer to four consecutive BYTEs in order
- Xof increasing significance.
- X*/
- Xvoid splitlong(bytes, bigword)
- XBYTE bytes[];
- Xlong bigword;
- X{
- X * (long *) bytes = bigword;
- X}
- X#endif /* FIZ */
- X
- X/*******************
- Xsplitint() converts an integer to two consecutive BYTEs in order
- Xof increasing significance.
- X*/
- Xvoid splitint(bytes, word)
- XBYTE bytes[];
- Xint word;
- X{
- X * (int *) bytes = word;
- X}
- X
- X/**********************
- Xto_int() converts two consecutive bytes, in order of increasing
- Xsignificance, to an integer.
- X*/
- Xint to_int(data)
- XBYTE data[];
- X{
- X return (*(int *) data);
- X}
- X
- X#endif /* ifndef TURBOC .. else ... */
- X
- X#ifndef FIZ
- X/**********************
- XFunction frd_zooh() reads the header of a Zoo archive in a machine-
- Xindependent manner, from a ZOOFILE.
- X*/
- Xint frd_zooh(zoo_header, zoo_file)
- Xstruct zoo_header *zoo_header;
- XZOOFILE zoo_file;
- X{
- X int status;
- X BYTE bytes[SIZ_ZOOH]; /* canonical header representation */
- X#ifdef TRACE_IO
- X if (verbose) {
- X printf("At file position [%8lx] ", ftell(zoo_file));
- X }
- X#endif
- X status = zooread (zoo_file, (char *) bytes, SIZ_ZOOH);
- X b_to_zooh (zoo_header, bytes); /* convert array to structure */
- X#ifdef TRACE_IO
- X if (verbose) {
- X printf("frd_zooh: reading\n");
- X show_h(zoo_header);
- X }
- X#endif
- X if (status < MINZOOHSIZ)
- X return (-1);
- X else
- X return (0);
- X}
- X#endif /* FIZ */
- X
- X/**********************
- XFunction frd_dir() reads a directory entry in a machine-independent manner,
- Xfrom a ZOOFILE.
- X*/
- Xint frd_dir(direntry, zoo_file)
- Xstruct direntry *direntry;
- XZOOFILE zoo_file;
- X{
- X int status;
- X BYTE bytes[MAXDIRSIZE]; /* big enough to hold variable part too */
- X
- X /* To simplify things, we read the maximum possible size of the
- X directory entry including the variable size and discard what is not
- X needed */
- X#ifdef TRACE_IO
- X if (verbose) {
- X printf("At file position [%8lx] ", ftell(zoo_file));
- X }
- X#endif
- X status = zooread (zoo_file, (char *) bytes, MAXDIRSIZE);
- X if (status < SIZ_DIR)
- X return (-1);
- X b_to_dir (direntry, bytes);
- X#ifdef TRACE_IO
- X if (verbose) {
- X printf("frd_dir: reading\n");
- X show_dir(direntry);
- X }
- X#endif
- X return (0);
- X}
- X
- X#ifndef FIZ
- X/***********************
- XFunction fwr_dir() writes a directory entry in a machine-independent manner
- Xto a ZOOFILE. Return value is -1 on error, else 0.
- X*/
- Xint fwr_dir(direntry, zoo_file)
- Xstruct direntry *direntry;
- XZOOFILE zoo_file;
- X{
- X int size;
- X BYTE bytes[MAXDIRSIZE];
- X assert (direntry->type <= 2);
- X size = dir_to_b (bytes, direntry);
- X#ifdef TRACE_IO
- X if (verbose) {
- X printf("At file position [%8lx] ", ftell(zoo_file));
- X printf("fwr_dir: writing\n");
- X show_dir(direntry);
- X }
- X#endif
- X
- X if (zoowrite (zoo_file, (char *) bytes, size) != size)
- X return (-1);
- X else
- X return (0);
- X}
- X
- X/***********************
- XFunction fwr_zooh() writes an archive header in a machine-independent manner
- Xto a ZOOFILE. Return value is -1 if error else 0.
- X*/
- Xint fwr_zooh(zoo_header, zoo_file)
- Xstruct zoo_header *zoo_header;
- XZOOFILE zoo_file;
- X{
- X BYTE bytes[SIZ_ZOOH]; /* was SIZ_DIR -- probably a typo */
- X int hsize; /* how much to write -- depends on header type */
- X hsize = MINZOOHSIZ; /* in case it's an old type 0 header */
- X if (zoo_header->type > 0) /* but if it's a newer header... */
- X hsize = SIZ_ZOOH; /* ...size of new type 1 header */
- X zooh_to_b (bytes, zoo_header);
- X if (zoowrite (zoo_file, (char *) bytes, hsize) != hsize)
- X return (-1);
- X else
- X return (0);
- X}
- X
- X/***********************
- Xb_to_zooh() converts an array of BYTE to a zoo_header structure.
- X*/
- Xvoid b_to_zooh (zoo_header, bytes)
- Xstruct zoo_header *zoo_header;
- XBYTE bytes[];
- X{
- X int i;
- X for (i = 0; i < SIZ_TEXT; i++) /* copy text */
- X zoo_header->text[i] = bytes[TEXT_I + i];
- X zoo_header->zoo_tag = to_long(&bytes[ZTAG_I]); /* copy zoo_tag */
- X zoo_header->zoo_start = to_long(&bytes[ZST_I]); /* copy zoo_start */
- X zoo_header->zoo_minus = to_long(&bytes[ZSTM_I]);
- X zoo_header->major_ver = bytes[MAJV_I]; /* copy versions */
- X zoo_header->minor_ver = bytes[MINV_I];
- X /* default is no archive comment and a header type of 0 */
- X zoo_header->type = 0;
- X zoo_header->acmt_pos = 0L;
- X zoo_header->acmt_len = 0;
- X zoo_header->vdata = 0;
- X if (zoo_header->zoo_start != FIXED_OFFSET) { /* if newer header */
- X zoo_header->type = bytes[HTYPE_I];
- X zoo_header->acmt_pos = to_long(&bytes[ACMTPOS_I]);
- X zoo_header->acmt_len = to_int(&bytes[ACMTLEN_I]);
- X zoo_header->vdata = bytes[HVDATA_I];
- X }
- X}
- X
- X/***********************
- Xzooh_to_b() converts a zoo_header structure to an array of BYTE.
- X*/
- Xvoid zooh_to_b (bytes, zoo_header)
- Xstruct zoo_header *zoo_header;
- XBYTE bytes[];
- X{
- X int i;
- X for (i = 0; i < SIZ_TEXT; i++) /* copy text */
- X bytes[TEXT_I + i] = zoo_header->text[i];
- X splitlong (&bytes[ZTAG_I], zoo_header->zoo_tag);
- X splitlong (&bytes[ZST_I], zoo_header->zoo_start);
- X splitlong (&bytes[ZSTM_I], zoo_header->zoo_minus);
- X bytes[MAJV_I] = zoo_header->major_ver; /* copy versions */
- X bytes[MINV_I] = zoo_header->minor_ver;
- X bytes[HTYPE_I] = zoo_header->type; /* header type */
- X if (zoo_header->type > 0) {
- X splitlong (&bytes[ACMTPOS_I], zoo_header->acmt_pos); /* comment posn */
- X splitint (&bytes[ACMTLEN_I], zoo_header->acmt_len); /* comment len */
- X bytes[HVDATA_I] = zoo_header->vdata; /* version data */
- X }
- X} /* zooh_to_b() */
- X
- X/************************
- Xdir_to_b() converts a directory entry structure to an array of BYTE.
- X*/
- Xint dir_to_b (bytes, direntry)
- Xstruct direntry *direntry;
- XBYTE bytes[];
- X{
- X int i;
- X int cursize;
- X int fixsize;
- X int totalsize;
- X splitlong(&bytes[DTAG_I], direntry->zoo_tag);
- X bytes[DTYP_I] = direntry->type ;
- X bytes[PKM_I] = direntry->packing_method ;
- X splitlong(&bytes[NXT_I], direntry->next);
- X splitlong(&bytes[OFS_I], direntry->offset);
- X splitint(&bytes[DAT_I], direntry->date);
- X splitint(&bytes[TIM_I], direntry->time);
- X splitint(&bytes[CRC_I], direntry->file_crc);
- X splitlong(&bytes[ORGS_I], direntry->org_size);
- X splitlong(&bytes[SIZNOW_I], direntry->size_now);
- X bytes[DMAJ_I] = direntry->major_ver;
- X bytes[DMIN_I] = direntry->minor_ver;
- X bytes[DEL_I] = direntry->deleted;
- X bytes[STRUC_I] = direntry->struc;
- X splitlong(&bytes[CMT_I], direntry->comment);
- X splitint(&bytes[CMTSIZ_I], direntry->cmt_size);
- X for (i = 0; i < FNM_SIZ; i++)
- X bytes[FNAME_I + i] = direntry->fname[i];
- X bytes[TZ_I] = NO_TZ; /* assume unknown */
- X bytes[NAMLEN_I] = 0;
- X bytes[DIRLEN_I] = 0;
- X
- X cursize = SIZ_DIR; /* to count size of directory */
- X fixsize = SIZ_DIR; /* size of fixed part */
- X assert (direntry->type <= 2);
- X if (direntry->type == 2) { /* handle stuff relevant to type 2 */
- X cursize = SIZ_DIRL;
- X fixsize = SIZ_DIRL;
- X bytes[TZ_I] = direntry->tz;
- X assert(direntry->namlen < 256 && direntry->namlen >= 0);
- X cursize += 2; /* space for namlen and dirlen */
- X if (direntry->namlen != 0) {
- X bytes[NAMLEN_I] = direntry->namlen;
- X for (i = 0; i < direntry->namlen; i++)
- X bytes[LFNAME_I+i] = direntry->lfname[i];
- X cursize += direntry->namlen;
- X }
- X assert(direntry->dirlen < 256 && direntry->dirlen >= 0);
- X if (direntry->dirlen != 0) {
- X bytes[DIRLEN_I] = direntry->dirlen;
- X for (i = 0; i < direntry->dirlen; i++)
- X bytes[cursize+i] = direntry->dirname[i];
- X cursize += direntry->dirlen;
- X }
- X /* Can't store system id if no namlen & dirlen...BUG!...now fixed.
- X Fortunately, system_id was always 0 so far so it probably
- X got interpreted as namlen=0 and dirlen=0 (2 bytes) */
- X splitint(&bytes[cursize], direntry->system_id);
- X cursize += 2;
- X bytes[cursize] = direntry->fattr & 0xff; /* byte 0 */
- X splitint(&bytes[cursize+1], (int) (direntry->fattr >> 8)); /* 1 & 2 */
- X cursize += 3;
- X bytes[cursize] = (direntry->vflag & 0xff); /* version flag */
- X splitint(&bytes[cursize+1], direntry->version_no); /* version number */
- X cursize += 3;
- X }
- X
- X splitint(&bytes[VARDIRLEN_I], direntry->var_dir_len);
- X assert(cursize ==
- X ((bytes[DIRLEN_I] > 0 || bytes[NAMLEN_I] > 0) ? 2 : 0) +
- X fixsize + bytes[DIRLEN_I] + bytes[NAMLEN_I]
- X );
- X
- X /* total size of dir entry is size of fixed part + size of var. part */
- X totalsize = fixsize + direntry->var_dir_len;
- X
- X /* Do CRC assuming CRC field is zero, and stuff CRC into field. */
- X splitint(&bytes[DCRC_I], 0); /* fill with zeroes */
- X crccode = 0;
- X /* avoid mixing pointers to signed and unsigned char */
- X addbfcrc((char *) bytes, totalsize); /* update CRC */
- X splitint(&bytes[DCRC_I], crccode);
- X
- X /* return total length of directory entry */
- X return (totalsize);
- X
- X} /* dir_to_b() */
- X#endif /* FIZ */
- X
- X/* b_to_dir() converts bytes to directory entry structure. The CRC of the
- Xdirectory bytes, if any, is checked and a zero or nonzero value is returned
- Xin direntry->dir_crc according as the check is good or bad */
- X
- Xvoid b_to_dir(direntry, bytes)
- Xstruct direntry *direntry;
- XBYTE bytes[];
- X{
- X int i;
- X int sysid_offs; /* temp variable */
- X unsigned int savecrc;
- X direntry->zoo_tag = to_long(&bytes[DTAG_I]);
- X direntry->type = bytes[DTYP_I];
- X direntry->packing_method = bytes[PKM_I];
- X direntry->next = to_long(&bytes[NXT_I]);
- X direntry->offset = to_long(&bytes[OFS_I]);
- X direntry->date = to_int(&bytes[DAT_I]);
- X direntry->time = to_int(&bytes[TIM_I]);
- X direntry->file_crc = to_int(&bytes[CRC_I]);
- X direntry->org_size = to_long(&bytes[ORGS_I]);
- X direntry->size_now = to_long(&bytes[SIZNOW_I]);
- X direntry->major_ver = bytes[DMAJ_I];
- X direntry->minor_ver = bytes[DMIN_I];
- X direntry->deleted = bytes[DEL_I];
- X direntry->struc = bytes[STRUC_I];
- X direntry->comment = to_long(&bytes[CMT_I]);
- X direntry->cmt_size = to_int(&bytes[CMTSIZ_I]);
- X /* for now, versions not implemented */
- X direntry->vflag = 0;
- X direntry->version_no = 0;
- X for (i = 0; i < FNM_SIZ; i++)
- X direntry->fname[i] = bytes[FNAME_I + i];
- X
- X /* start by assuming variable part is zero bytes */
- X direntry->var_dir_len = direntry->dir_crc = 0;
- X direntry->namlen = direntry->dirlen = 0;
- X direntry->lfname[0] = direntry->dirname[0] = '\0';
- X direntry->tz = NO_TZ; /* assume unknown */
- X direntry->system_id = SYSID_NIX; /* default system_id if not present */
- X direntry->fattr = NO_FATTR; /* assume none */
- X
- X assert (direntry->type <= 2);
- X if (direntry->type == 2) {
- X direntry->var_dir_len = to_int(&bytes[VARDIRLEN_I]);
- X assert(direntry->var_dir_len <= MAXDIRSIZE);
- X if (direntry->var_dir_len > MAXDIRSIZE)
- X direntry->var_dir_len = MAXDIRSIZE;
- X direntry->tz = bytes[TZ_I];
- X if (direntry->var_dir_len > 0)
- X direntry->namlen = bytes[NAMLEN_I];
- X if (direntry->var_dir_len > 1)
- X direntry->dirlen = bytes[DIRLEN_I];
- X for (i = 0; i < direntry->namlen; i++)
- X direntry->lfname[i] = bytes[LFNAME_I + i];
- X for (i = 0; i < direntry->dirlen; i++)
- X direntry->dirname[i] = bytes[DIRNAME_I + direntry->namlen + i];
- X sysid_offs = DIRNAME_I + direntry->namlen + i; /* offset of system id */
- X if (direntry->var_dir_len > direntry->namlen + direntry->dirlen + 2) {
- X direntry->system_id = to_int(&bytes[sysid_offs]);
- X }
- X if (direntry->var_dir_len > direntry->namlen + direntry->dirlen + 4) {
- X direntry->fattr = ((unsigned long) bytes[sysid_offs + 2]) |
- X ((unsigned long) bytes[sysid_offs + 3] << 8) |
- X ((unsigned long) bytes[sysid_offs + 4] << 16);
- X }
- X if (direntry->var_dir_len > direntry->namlen + direntry->dirlen + 7) {
- X direntry->vflag = bytes[sysid_offs + 5];
- X direntry->version_no = to_int(&bytes[sysid_offs + 6]);
- X }
- X /* do CRC calculation */
- X savecrc = (unsigned int) to_int(&bytes[DCRC_I]);
- X crccode = 0;
- X splitint(&bytes[DCRC_I], 0);
- X addbfcrc((char *) bytes, SIZ_DIRL + direntry->var_dir_len);
- X direntry->dir_crc = crccode - savecrc;
- X }
- X}
- X
- X#ifdef FILTER
- X#define TWOBYTES 2 /* better than literal 2; figure out why */
- X
- X/* rdint() reads two bytes from standard input in archive order */
- Xint rdint (val)
- Xunsigned int *val;
- X{
- X BYTE bytes[TWOBYTES];
- X if (zooread (STDIN, bytes, TWOBYTES) == TWOBYTES) {
- X *val = to_int(bytes);
- X return (0);
- X } else
- X return (1);
- X}
- X
- X/* wrint() writes an unsigned int to standard output in archive order */
- Xint wrint (val)
- Xunsigned int val;
- X{
- X BYTE bytes[TWOBYTES];
- X splitint (bytes, val);
- X if (zoowrite (STDOUT, bytes, TWOBYTES) == TWOBYTES)
- X return (0);
- X else
- X return (1);
- X}
- X#endif /* FILTER */
- X
- X#ifdef TRACE_IO
- X/* dump contents of archive header */
- Xvoid show_h (zoo_header)
- Xstruct zoo_header *zoo_header;
- X{
- X int i;
- X printf ("Header text:\n");
- X for (i = 0; i < SIZ_TEXT; i++) { /* ASSUMES ASCII TEXT */
- X int c;
- X c = zoo_header->text[i];
- X if (c >= ' ' && c < 0x7f)
- X putchar (c);
- X else {
- X putchar ('^');
- X putchar (i & 0x40);
- X }
- X }
- X putchar('\n');
- X printf ("zoo_tag = [%8lx] zoo_start = [%8lx] zoo_minus = [%8lx]\n",
- X zoo_header->zoo_tag, zoo_header->zoo_start,
- X zoo_header->zoo_minus);
- X printf ("major_ver.minor_ver = [%d.%d]\n",
- X zoo_header->major_ver, zoo_header->minor_ver);
- X if (zoo_header->zoo_start != FIXED_OFFSET) {
- X printf ("type = [%d] ", zoo_header->type);
- X printf ("acmt_pos = [%8lx] acmt_len = [%4x] vdata = [%2x]",
- X zoo_header->acmt_pos, zoo_header->acmt_len, zoo_header->vdata);
- X printf ("\n");
- X }
- X printf ("---------\n");
- X}
- X
- X/* dump contents of directory entry */
- Xvoid show_dir (direntry)
- Xstruct direntry *direntry;
- X{
- X printf ("Directory entry for file [%s][%s]:\n",
- X direntry->fname, direntry->lfname);
- X printf ("tag = [%8lx] type = [%d] PM = [%d] Next = [%8lx] Offset = [%8lx]\n",
- X direntry->zoo_tag, (int) direntry->type,
- X (int) direntry->packing_method, direntry->next,
- X direntry->offset);
- X printf ("Orig size = [%ld] Size now = [%ld] dmaj_v.dmin_v = [%d.%d]\n",
- X direntry->org_size, direntry->size_now,
- X (int) direntry->major_ver, (int) direntry->minor_ver);
- X printf ("Struc = [%d] DEL = [%d] comment_offset = [%8lx] cmt_size = [%d]\n",
- X (int) direntry->struc, (int) direntry->deleted, direntry->comment,
- X direntry->cmt_size);
- X printf ("var_dir_len = [%d] TZ = [%d] dir_crc = [%4x]\n",
- X direntry->var_dir_len, (int) direntry->tz, direntry->dir_crc);
- X printf ("system_id = [%d] dirlen = [%d] namlen = [%d] fattr=[%24lx]\n",
- X direntry->system_id, direntry->dirlen, direntry->namlen, direntry->fattr);
- X printf ("vflag = [%4x] version_no = [%4x]\n",
- X direntry->vflag, direntry->version_no);
- X if (direntry->dirlen > 0)
- X printf ("dirname = [%s]\n", direntry->dirname);
- X printf ("---------\n");
- X}
- X#endif /* TRACE_IO */
- END_OF_FILE
- if test 21282 -ne `wc -c <'portable.c'`; then
- echo shar: \"'portable.c'\" unpacked with wrong size!
- fi
- # end of 'portable.c'
- fi
- if test -f 'zooext.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'zooext.c'\"
- else
- echo shar: Extracting \"'zooext.c'\" \(21819 characters\)
- sed "s/^X//" >'zooext.c' <<'END_OF_FILE'
- X#ifndef LINT
- X/* @(#) zooext.c 2.21 88/08/24 02:39:04 */
- Xstatic char sccsid[]="@(#) zooext.c 2.21 88/08/24 02:39:04";
- X#endif /* LINT */
- X
- X/*
- XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- X(C) Copyright 1988 Rahul Dhesi -- All rights reserved
- X*/
- X#include "options.h"
- X/* Extract file from archive. Extracts files specified in parameter-list
- X from archive zoo_path. If none specified, extracts all files from
- X archive. */
- X
- X#include "zoo.h"
- X#include "parse.h" /* defines struct for parse() */
- X
- X#include "portable.h" /* portable I/O definitions */
- X#include "machine.h" /* machine-specific declarations */
- X
- X#include "zooio.h"
- X#include "various.h"
- X
- X#ifndef NOSIGNAL
- X#include <signal.h>
- X#endif
- X
- X#include "zoofns.h"
- X
- X#ifdef LINT_ARGS
- Xint makepath (char *);
- Xint needed (char *, struct direntry *, struct zoo_header *);
- Xvoid putstr (char *);
- X#else
- Xint needed ();
- Xint makepath ();
- Xvoid putstr ();
- X#endif
- X
- X#ifdef FATTR
- Xint setfattr PARMS ((char *, unsigned long));
- X#endif /* FATTR */
- X
- Xextern int quiet;
- X
- X#include "errors.i"
- X
- X/* Following two are used by ctrl_c() also, hence declared here */
- Xchar extfname[LFNAMESIZE]; /* filename of extracted file */
- Xchar prtfname[LFNAMESIZE]; /* name of extracted file on screen */
- Xstatic ZOOFILE this_file; /* file to extract */
- X
- Xstatic int tofile; /* true if not pipe or null device */
- Xextern unsigned int crccode;
- Xextern char *out_buf_adr; /* address of output buffer */
- X
- Xvoid zooext(zoo_path, option)
- Xchar *zoo_path, *option;
- X{
- Xchar *whichname; /* which name to extract */
- Xchar matchname[PATHSIZE]; /* for pattern matching only */
- X#ifndef NOSIGNAL
- Xint (*oldsignal)(); /* to save previous SIGINT handler */
- X#endif
- XZOOFILE zoo_file; /* open archive */
- Xlong next_ptr; /* pointer to within archive */
- Xstruct zoo_header zoo_header; /* header for archive */
- Xint status; /* error status */
- Xint exit_status = 0; /* exit status */
- Xint error_message; /* Whether to give error message */
- Xunsigned long disk_space; /* disk space left */
- Xint matched = 0; /* Any files matched? */
- Xint overwrite = 0; /* force overwrite of files? */
- Xint supersede = 0; /* supersede newer files? */
- Xint needdel = 0; /* extract deleted files too */
- Xint usepath = 0; /* use path for extraction */
- Xint todot = 0; /* extract relative to . */
- Xint badcrc_count = 0; /* how many files with bad CRC */
- Xint bad_header = 0; /* to avoid spurious messages later */
- Xlong fiz_ofs = 0; /* offset where to start */
- Xlong dat_ofs = 0; /* .. and offset of file data */
- Xint pipe = 0; /* are we piping output? */
- Xint null_device = 0; /* are we sending to null device? */
- X#ifndef PORTABLE
- Xint fast_ext = 0; /* fast extract as *.?Z? */
- Xint alloc_size; /* disk allocation unit size */
- X#endif
- Xstruct direntry direntry; /* directory entry */
- Xint first_dir = 1; /* first dir entry seen? */
- X
- Xstatic char extract_ver[] = "Zoo %d.%d is needed to extract %s.\n";
- Xstatic char no_space[] = "Insufficient disk space to extract %s.\n";
- X
- Xwhile (*option) {
- X switch (*option) {
- X#ifndef PORTABLE
- X case 'z': fast_ext++; break;
- X#endif
- X case 'x':
- X case 'e': break;
- X case 'N': null_device++; break;
- X case 'O': overwrite += 2; break;
- X case 'o': overwrite++; break;
- X case 'p': pipe++; break;
- X case 'S': supersede++; break;
- X case 'd': needdel++; break;
- X case 'q': quiet++; break;
- X case '/': usepath++; break;
- X case '.': todot++; break;
- X case '@': /* if @m,n specified, fiz_ofs = m, dat_ofs = n */
- X {
- X char *comma_pos;
- X ++option;
- X comma_pos = strchr(option, ',');
- X if (comma_pos != NULL) {
- X dat_ofs = calc_ofs (comma_pos + 1);
- X *comma_pos = '\0';
- X }
- X fiz_ofs = calc_ofs(option);
- X goto no_more;
- X }
- X default:
- X prterror ('f', inv_option, *option);
- X /* break; */
- X }
- X option++;
- X}
- X
- Xno_more: /* come from exit in while loop above */
- X
- X
- Xif (overwrite == 1) /* must be at least 2 to begin with */
- X overwrite--;
- X
- Xif (null_device && pipe) {
- X prterror ('f', inv_option, 'p');
- X pipe = 0;
- X}
- X
- Xif (overwrite && pipe)
- X prterror ('w', option_ignored, 'O');
- X
- X#ifndef PORTABLE
- Xif (null_device && fast_ext) {
- X prterror ('w', inv_option, 'N');
- X null_device = 0;
- X}
- X#endif
- X
- Xtofile = !pipe && !null_device; /* sending to actual file */
- X
- Xzoo_file = zooopen(zoo_path, Z_READ);
- X
- Xif (zoo_file == NOFILE)
- X prterror ('f', could_not_open, zoo_path);
- X
- Xif (fiz_ofs != 0L) { /* if offset specified, start there */
- X prterror ('m', start_ofs, fiz_ofs, dat_ofs);
- X zooseek (zoo_file, fiz_ofs, 0);
- X} else {
- X /* read header */
- X frd_zooh (&zoo_header, zoo_file);
- X if ((zoo_header.zoo_start + zoo_header.zoo_minus) != 0L) {
- X prterror ('w', failed_consistency);
- X bad_header++;
- X exit_status = 1;
- X }
- X zooseek (zoo_file, zoo_header.zoo_start, 0); /* seek to where data begins */
- X}
- X
- X#ifndef PORTABLE
- Xdisk_space = space (0, &alloc_size); /* remember disk space left */
- X#else
- Xdisk_space = MAXLONG; /* infinite disk space */
- X#endif
- X
- X/* if piping output we open the output device just once */
- Xif (null_device) {
- X this_file = NULLFILE;
- X} else if (pipe)
- X this_file = STDOUT; /* standard output */
- X
- Xwhile (1) {
- X frd_dir (&direntry, zoo_file);
- X if (direntry.zoo_tag != ZOO_TAG) {
- X long currpos, zoolength;
- X prterror ('F', invalid_header);
- X
- X /* Note: if header was bad, there's no point trying to find
- X how many more bytes aren't processed -- our seek position is
- X likely very wrong */
- X
- X if (!bad_header)
- X if ((currpos = zootell (zoo_file)) != -1L)
- X if (zooseek (zoo_file, 0L, 2) != -1)
- X if ((zoolength = zootell (zoo_file)) != -1L)
- X printf (cant_process, zoolength - currpos);
- X zooexit (1);
- X }
- X if (direntry.next == 0L) { /* END OF CHAIN */
- X break; /* EXIT on end of chain */
- X }
- X /* when first direntry read, change dat_ofs from abs. pos. to rel. offset */
- X if (first_dir && dat_ofs != 0) {
- X dat_ofs -= direntry.offset;
- X first_dir = 0;
- X }
- X next_ptr = direntry.next + dat_ofs; /* ptr to next dir entry */
- X
- X whichname = choosefname(&direntry); /* which filename */
- X whichname = strdup(whichname); /* bug fix */
- X fixfname(whichname); /* fix syntax */
- X strcpy (matchname, fullpath (&direntry)); /* get full pathname */
- X if (zoo_header.vdata & VFL_ON)
- X add_version (matchname, &direntry); /* add version suffix */
- X
- X/* if extraction to subtree rooted at curr dir, modify pathname */
- X#if 0
- X#ifdef DIR_LBRACK
- X if (todot && direntry.dirname[0] == *DIR_LBRACK &&
- X direntry.dirname[1] != *CUR_DIR) {
- X char tmpstr[PATHSIZE];
- X strcpy (tmpstr, DIR_LBRACK);
- X strcat (tmpstr, CUR_DIR);
- X strcat (tmpstr, &direntry.dirname[1]);
- X strcpy (direntry.dirname, tmpstr);
- X }
- X#endif
- X#endif
- X
- X /* hard-coded '/' should be eventually removed */
- X if (todot && *direntry.dirname == '/') {
- X char tmpstr[PATHSIZE];
- X strcpy(tmpstr, direntry.dirname);
- X strcpy(direntry.dirname,CUR_DIR);
- X strcat(direntry.dirname, tmpstr);
- X }
- X
- X /* matchname now holds the full pathname for pattern matching */
- X
- X if ( ( (needdel && direntry.deleted) ||
- X (needdel < 2 && !direntry.deleted)
- X ) && needed(matchname, &direntry, &zoo_header)) {
- X matched++; /* update count of files extracted */
- X
- X if (direntry.major_ver > MAJOR_EXT_VER ||
- X (direntry.major_ver == MAJOR_EXT_VER &&
- X direntry.minor_ver > MINOR_EXT_VER)) {
- X prterror ('e', extract_ver, direntry.major_ver,
- X direntry.minor_ver, whichname);
- X exit_status = 1;
- X goto loop_again;
- X }
- X
- X /*
- X If extracting to null device, or if user requested extraction
- X of entire path, include any directory name in filename.
- X If extraction to current directory requested, and if extfname
- X begins with path separator, fix it */
- X
- X strcpy (extfname, whichname);
- X if ((usepath || null_device) && direntry.dirlen != 0) {
- X combine(extfname, direntry.dirname, whichname);
- X if (usepath > 1 && !null_device)
- X makepath(direntry.dirname); /* make dir prefix */
- X }
- X
- X strcpy(prtfname, extfname);
- X if (zoo_header.vdata & VFL_ON)
- X add_version (prtfname, &direntry);
- X
- X if (tofile) {
- X int present = 0;
- X
- X#ifndef PORTABLE
- X /*
- X if Z format (fast) extraction, extension is created as
- X follows: for no current extension, new extension is "zzz";
- X for current extension "a", new extension is "azz"; for
- X current extension "ab", new extension is "azb"; and for
- X current extension "abc", new extension is "azc".
- X */
- X
- X if (fast_ext) {
- X int length;
- X struct path_st path_st;
- X parse (&path_st, extfname); /* split filename */
- X strcpy (extfname, path_st.fname); /* just root filename */
- X length = strlen (path_st.ext);
- X strcat (extfname, ".");
- X if (length == 0)
- X strcat (extfname, "zzz"); /* no ext -> .zzz */
- X else if (length == 1) {
- X strcat (extfname, path_st.ext);
- X strcat (extfname, "zz"); /* *.? -> *.?zz */
- X } else { /* length is 2 or 3 */
- X if (length == 2) /* allow .aa, .ab, etc. */
- X path_st.ext[2] = path_st.ext[1];
- X path_st.ext[1] = 'z';
- X strcat (extfname, path_st.ext); /* *.?? -> *.?z? */
- X }
- X strcpy(prtfname, direntry.fname);
- X add_version (prtfname, &direntry);
- X }
- X#endif /* ifndef PORTABLE */
- X
- X /* don't extract if archived file is older than disk copy */
- X if (!supersede && exists(extfname)) {
- X unsigned int ddate, dtime;
- X#ifdef GETUTIME
- X getutime (extfname, &ddate, &dtime);
- X#else
- X ZOOFILE tfile;
- X ddate = dtime = 0xffff; /* assume maximum */
- X tfile = zooopen(extfname, Z_READ);
- X if (tfile == NOFILE)
- X goto loop_again;
- X gettime (tfile, &ddate, &dtime);
- X zooclose (tfile);
- X#endif
- X if (cmpnum (direntry.date, direntry.time, ddate, dtime) <= 0) {
- X prterror ('m', "%-14s -- skipped\n", prtfname);
- X goto loop_again;
- X }
- X }
- X
- X if (overwrite) {
- X this_file = zoocreate (extfname);
- X#ifdef FATTR
- X /* if can't open file, and OO option, make it writable first */
- X if (this_file == NOFILE && overwrite >= 4 &&
- X (direntry.fattr >> 22) == 1 && exists(extfname)) {
- X setfattr (extfname, (unsigned long) (1L << 7) | direntry.fattr);
- X this_file = zoocreate (extfname);
- X }
- X#endif /* FATTR */
- X } else {
- X if (exists (extfname)) {
- X present = 1;
- X this_file = NOFILE;
- X } else
- X this_file = zoocreate (extfname);
- X }
- X error_message = 1;
- X if (this_file == NOFILE) {
- X if (present == 1) { /* if file exists already */
- X char ans[20]; /* answer to "Overwrite?" */
- X do {
- X#ifdef EXT_ANYWAY
- X printf ("%s exists; extract anyway? [Yes/No/All] ",
- X extfname);
- X#else
- X printf ("Overwrite %s (Yes/No/All)? ", extfname);
- X#endif
- X fflush (stdin);
- X fgets (ans, sizeof(ans), stdin);
- X strlwr (ans);
- X } while (*ans != 'y' && *ans != 'n' && *ans != 'a');
- X
- X if (*ans == 'a')
- X overwrite++;
- X if (*ans == 'y' || *ans == 'a') {
- X this_file = zoocreate(extfname);
- X error_message = 1; /* give error message if open fails */
- X } else {
- X error_message = 0; /* user said 'n', so no error message */
- X }
- X } else {
- X error_message = 1; /* Real error -- give error message */
- X }
- X } /* end if */
- X } /* end if */
- X
- X if (this_file == NOFILE) { /* file couldn't be opened */
- X if (error_message == 1) {
- X prterror ('e', "Can't open %s for output.\n", extfname);
- X exit_status = 1;
- X
- X#ifndef PORTABLE
- X /* if error was due to full disk, abort */
- X if (space(0, &alloc_size) < alloc_size)
- X prterror ('f', disk_full);
- X#endif
- X
- X }
- X } else if (zooseek (zoo_file, (direntry.offset + dat_ofs), 0) == -1L) {
- X prterror ('e', "Could not seek to file data.\n");
- X exit_status = 1;
- X close_file (this_file);
- X } else {
- X#ifndef PORTABLE
- X /* check msdos's free disk space if we seem to be running low
- X (within 1 cluster of being full) */
- X if (tofile && disk_space < direntry.org_size + alloc_size) {
- X disk_space = space (0, &alloc_size);
- X if (disk_space < alloc_size) {
- X close_file (this_file);
- X unlink (extfname);
- X prterror ('f', disk_full);
- X }
- X }
- X#endif
- X if (tofile && disk_space < direntry.org_size) {
- X#ifdef PORTABLE
- X ;
- X#else
- X prterror ('e', no_space, prtfname);
- X unlink (extfname); /* delete any created file */
- X#endif /* portable */
- X
- X } else {
- X
- X#ifndef PORTABLE
- X if (fast_ext) { /* fast ext -> create header */
- X#ifdef LINT_ARGS
- X void make_tnh (struct tiny_header *, struct direntry *);
- X#else
- X void make_tnh();
- X#endif
- X struct tiny_header tiny_header;
- X make_tnh(&tiny_header, &direntry);
- X zoowrite (this_file, (char *) &tiny_header, sizeof(tiny_header));
- X
- X if (direntry.cmt_size != 0) { /* copy comment */
- X long save_pos;
- X save_pos = zootell (zoo_file);
- X zooseek (zoo_file, direntry.comment, 0);
- X getfile (zoo_file, this_file,
- X (long) direntry.cmt_size, 0);
- X zooseek (zoo_file, save_pos, 0);
- X }
- X }
- X#endif /* ifndef PORTABLE */
- X
- X crccode = 0; /* Initialize CRC before extraction */
- X if (!pipe) {
- X#ifdef PORTABLE
- X prterror ('m', "%-14s -- ", prtfname);
- X#else
- X if (fast_ext)
- X prterror ('m', "%-12s ==> %-12s -- ",
- X prtfname, extfname);
- X else
- X prterror ('m', "%-12s -- ", prtfname);
- X#endif /* PORTABLE */
- X
- X } else { /* must be pipe */
- X prterror ('M',"\n\n********\n%s\n********\n",prtfname);
- X
- X#ifdef SETMODE
- X MODE_BIN(this_file); /* make std output binary so
- X ^Z won't cause error */
- X#endif
- X }
- X#ifndef NOSIGNAL
- X if (tofile)
- X {
- X oldsignal = signal (SIGINT, SIG_IGN);
- X if (oldsignal != SIG_IGN)
- X signal (SIGINT, ctrl_c); /* Trap ^C & erase partial file */
- X }
- X#endif /* not NOSIGNAL */
- X
- X if (direntry.packing_method == 0)
- X /* 4th param 1 means CRC update */
- X status = getfile (zoo_file, this_file, direntry.size_now, 1);
- X
- X#ifndef PORTABLE
- X else if (fast_ext)
- X /* 4th param 0 means no CRC update */
- X status = getfile (zoo_file, this_file, direntry.size_now, 0);
- X#endif
- X
- X else if (direntry.packing_method == 1) {
- X#ifdef UNBUF_IO
- X /* NOT PORTABLE -- DO NOT TRY THIS AT HOME */
- X long lseek PARMS ((int, long, int));
- X long tell PARMS ((int));
- X int this_fd, zoo_fd;
- X
- X /* get file descriptors */
- X this_fd = null_device ? -2 : fileno (this_file);
- X zoo_fd = fileno (zoo_file);
- X
- X zooseek (zoo_file, zootell (zoo_file), 0); /* synch */
- X lseek (zoo_fd, zootell (zoo_file), 0); /* ..again */
- X if (!null_device) {
- X zooseek (this_file, zootell (this_file), 0); /* synch */
- X lseek (this_fd, zootell (this_file), 0); /* ..again */
- X }
- X status = lzd(zoo_fd, this_fd); /* uncompress */
- X zooseek (zoo_file, tell (zoo_fd), 0); /* resynch */
- X if (!null_device)
- X zooseek (this_file, tell (this_fd), 0);/* resynch */
- X#else
- X status = lzd (zoo_file, this_file); /* uncompress */
- X#endif
- X } else {
- X prterror ('e', "File %s: impossible packing method.\n",
- X whichname);
- X unlink(extfname);
- X goto loop_again;
- X }
- X
- X
- X#ifndef NOSIGNAL
- X if (tofile)
- X signal (SIGINT, oldsignal);
- X#endif /* not NOSIGNAL */
- X
- X#ifdef SETMODE
- X if (pipe)
- X MODE_TEXT(this_file); /* restore text mode */
- X#endif
- X
- X if (tofile) {
- X /* set date/time of file being extracted */
- X#ifdef GETTZ
- X void tzadj();
- X /* adjust for original timezone */
- X tzadj (&direntry);
- X#endif
- X#ifdef NIXTIME
- X close_file (this_file);
- X setutime (extfname, direntry.date, direntry.time);
- X#else
- X settime (this_file, direntry.date, direntry.time);
- X close_file (this_file);
- X#endif
- X#ifdef FATTR
- X/* Restore file attributes. Bit 23==1 means system-specific; we currently
- Xdon't recognize this. Bit 23==0 means use portable format, in which case
- Xbit 22==0 means ignore attributes. Thus attributes are ignored if both
- Xbits 23 and 22 are zero, which is the effect of a zero-filled file
- Xattribute field. Currently we restore file attributes if and only if
- Xbit 23==0 and bit 22==1. */
- X
- X if ((direntry.fattr >> 22) == 1) {
- X setfattr (extfname, direntry.fattr);
- X }
- X#endif /* FATTR */
- X } /* end of if (tofile) ... */
- X if (status != 0) {
- X exit_status = 1;
- X if (tofile)
- X unlink (extfname);
- X if (status == 1) {
- X memerr();
- X /* To avoid spurious errors due to ^Z being sent to screen,
- X we don't check for I/O error if output was piped */
- X } else if (!pipe && (status == 2 || status == 3)) {
- X prterror ('e', no_space, prtfname);
- X }
- X } else {
- X /* file extracted, so update disk space. */
- X /* we subtract the original size of the file, rounded
- X UP to the nearest multiple of the disk allocation
- X size. */
- X#ifndef PORTABLE
- X {
- X unsigned long temp;
- X temp = (direntry.org_size + alloc_size) / alloc_size;
- X disk_space -= temp * alloc_size;
- X }
- X#endif
- X
- X if (
- X#ifndef PORTABLE
- X !fast_ext &&
- X#endif
- X direntry.file_crc != crccode
- X ) {
- X badcrc_count++;
- X exit_status = 1;
- X if (!pipe) {
- X if (!null_device)
- X prterror ('M', "extracted ");
- X prterror ('w', bad_crc, prtfname);
- X }
- X else { /* duplicate to standard error */
- X static char stars[] = "\n******\n";
- X putstr (stars);
- X prterror ('w', bad_crc, prtfname);
- X putstr (stars);
- X fprintf (stderr, "WARNING: ");
- X fprintf (stderr, bad_crc, prtfname);
- X }
- X } else
- X if (!pipe)
- X prterror ('M', null_device ? "OK\n" : "extracted\n");
- X
- X } /* end if */
- X } /* end if */
- X } /* end if */
- X } /* end if */
- X
- Xloop_again:
- X zooseek (zoo_file, next_ptr, 0); /* ..seek to next dir entry */
- X} /* end while */
- X
- Xclose_file (zoo_file);
- Xif (!matched)
- X putstr (no_match);
- X
- Xif (badcrc_count) {
- X prterror ('w', "%d File(s) with bad CRC.\n", badcrc_count);
- X} else if (null_device)
- X prterror ('m', "Archive seems OK.\n");
- X
- Xzooexit (exit_status);
- X
- X} /* end zooext */
- X
- X/* close_file() */
- X/* closes a file if and only if we aren't sending output to
- X a pipe or to the null device */
- X
- Xvoid close_file (file)
- XZOOFILE file;
- X{
- X if (tofile)
- X zooclose (file);
- X}
- X
- X/* Ctrl_c() is called if ^C is hit while a file is being extracted.
- X It closes the files, deletes it, and exits. */
- Xint ctrl_c()
- X{
- X#ifndef NOSIGNAL
- X signal (SIGINT, SIG_IGN); /* ignore any more */
- X#endif
- X zooclose (this_file);
- X unlink (extfname);
- X zooexit (1);
- X}
- X
- X#ifndef PORTABLE
- X/* make_tnh copies creates a tiny_header */
- Xvoid make_tnh (tiny_header, direntry)
- Xstruct tiny_header *tiny_header;
- Xstruct direntry *direntry;
- X{
- X tiny_header->tinytag = TINYTAG;
- X tiny_header->type = 1;
- X tiny_header->packing_method = direntry->packing_method;
- X tiny_header->date = direntry->date;
- X tiny_header->time = direntry->time;
- X tiny_header->file_crc = direntry->file_crc;
- X tiny_header->org_size = direntry->org_size;
- X tiny_header->size_now = direntry->size_now;
- X tiny_header->major_ver = direntry->major_ver;
- X tiny_header->minor_ver = direntry->minor_ver;
- X tiny_header->cmt_size = direntry->cmt_size;
- X strcpy (tiny_header->fname, direntry->fname);
- X}
- X#endif /* ifndef PORTABLE */
- END_OF_FILE
- if test 21819 -ne `wc -c <'zooext.c'`; then
- echo shar: \"'zooext.c'\" unpacked with wrong size!
- fi
- # end of 'zooext.c'
- fi
- echo shar: End of archive 8 \(of 10\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 10 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-